using System;
using System.Xml;

namespace FreeFlow.Client
{
  /// <summary>Type of a date-time field.</summary>
  public enum DateTimeType
  {
    /// <summary>Date only.</summary>
    Date,
    /// <summary>Time only.</summary>
    Time,
    /// <summary>Date and time.</summary>
    DateTime
  }

	/// <summary>A date-time field.</summary>
	[Serializable]
	public class DateTimeField : Field
	{
    internal DateTimeField(Form form, XmlElement fieldNode)
      : base(form, fieldNode)
    {
      if (fieldNode != null)
      {
        string dateTimeTypeString = fieldNode.GetAttribute("Parts");
        if (dateTimeTypeString == "Time")
          dateTimeType = DateTimeType.Time;
        else if (dateTimeTypeString == "Date")
          dateTimeType = DateTimeType.Date;
        else if (dateTimeTypeString == "Both")
          dateTimeType = DateTimeType.DateTime;
        else
          throw new FreeFlowException("Unrecognized date-time type - " + dateTimeTypeString);
		
      }
    }

    internal override void FillValue(XmlElement node)
    {
      base.FillValue(node);
      
      // earliest and latest
      string earliestString = node.GetAttribute("Earliest");
      if (earliestString.Length == 0)
        earliest = Constants.NullDateTime;
      else
        earliest = DateTime.Parse(earliestString);
      
      string latestString = node.GetAttribute("Latest");
      if (latestString.Length == 0)
        latest = Constants.NullDateTime;
      else
        latest = DateTime.Parse(latestString);
    }

    /// <summary>
    /// Gets the validation message.
    /// </summary>
    /// <returns>Returns null if the field has no validation errors, an error message otherwise.</returns>
    public override string GetValidationMessage()
    {
      if (Usage == FieldUsage.Required)
      {
        if (DateTime == Constants.NullDateTime)
          return FieldMustBeCompleted;
      }

      // earliest
      if (earliest != Constants.NullDateTime)
        if (DateTime < earliest)
          return "Field's value is less than the earliest of " + earliest.ToString();

      // latest
      if (latest != Constants.NullDateTime)
        if (DateTime > latest)
          return "Field's value is greater than the latest of " + latest.ToString();

      // check blank values
      return base.GetValidationMessage();
    }

    #region properties
    private DateTimeType dateTimeType;
    /// <summary>
    /// Gets the date time type of the field.
    /// </summary>
    public DateTimeType DateTimeType
    {
      get
      {
        return dateTimeType;
      }
    }

    /// <summary>
    /// Gets or sets the value of the field in DateTime format.
    /// </summary>
    public DateTime DateTime
    {
      get
      {
        if (string.IsNullOrEmpty(Value))
          return Constants.NullDateTime;
        return DateTime.Parse(Value);
      }
      set
      {
        Value = value.ToString("s");
      }
    }

    private DateTime earliest = Constants.NullDateTime;
    /// <summary>
    /// Gets the earliest valid date-fime for this field.
    /// </summary>
    public DateTime Earliest
    {
      get
      {
        return earliest;
      }
    }

    private DateTime latest = Constants.NullDateTime;
    /// <summary>
    /// Gets the latest valid date-fime for this field.
    /// </summary>
    public DateTime Latest
    {
      get
      {
        return latest;
      }
    }
    #endregion
	}
}
